/**
  ******************************************************************************
  * @file    system_mm32f0160.c
  * @author  VV Team
  * @version V1.0.0
  * @date    2021.07.06
  * @brief   CMSIS Cortex-M0 Device Peripheral Access Layer System Source File.
  *
  * 1.  This file provides two functions and one global variable to be called from
  *     user application:
  *      - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
  *                      factors, AHB/APBx prescalers and Flash settings).
  *                      This function is called at startup just after reset and
  *                      before branch to main program. This call is made inside
  *                      the "startup_mm32f0160.s" file.
  *
  *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
  *                                  by the user application to setup the SysTick
  *                                  timer or configure other parameters.
  *
  *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
  *                                 be called whenever the core clock is changed
  *                                 during program execution.
  *
  * 2. After each device reset the HSI (8 MHz) is used as system clock source.
  *    Then SystemInit() function is called, in "startup_mm32f0160.s" file, to
  *    configure the system clock before to branch to main program.
  *
  * 3. If the system clock source selected by user fails to startup, the SystemInit()
  *    function will do nothing and HSI still used as system clock source. User can
  *    add some code to deal with this issue inside the SetSysClock() function.
  *
  *
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, MINDMOTION SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  ******************************************************************************
  */

/** @addtogroup CMSIS
  * @{
  */
#include "mm32_device.h"

/**
  * @}
  */

/**
  * @}
  */

/*!< Uncomment the line corresponding to the desired System clock (SYSCLK)
   frequency (after reset the HSI is used as SYSCLK source)

   IMPORTANT NOTE:
   ==============
   1. After each device reset the HSI is used as System clock source.

   2. Please make sure that the selected System clock doesn't exceed your device's
   maximum frequency.

   3. If none of the define below is enabled, the HSI is used as System clock
   source.

   4. The System clock configuration functions provided within this file assume that:
   - For Low, Medium and High density Value line devices an external 8MHz
   crystal is used to drive the System clock.
   - For Low, Medium and High density devices an external 8MHz crystal is
   used to drive the System clock.
   - For Connectivity line devices an external 25MHz crystal is used to drive
   the System clock.
   If you are using different crystal you have to adapt those functions accordingly.
  */

//#define SYSCLK_FREQ_HSE        HSE_VALUE
//#define SYSCLK_FREQ_24MHz      24000000UL
//#define SYSCLK_FREQ_36MHz      36000000UL
//#define SYSCLK_FREQ_48MHz      48000000UL
//#define SYSCLK_FREQ_XXMHz      72000000UL

//#define SYSCLK_HSI_24MHz       24000000UL
//#define SYSCLK_HSI_36MHz       36000000UL
//#define SYSCLK_HSI_48MHz       48000000UL
#define SYSCLK_HSI_XXMHz       72000000UL

/*!< Uncomment the following line if you need to relocate your vector Table in
   Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET        0x0     /*!< Vector Table base offset field.
                                          This value must be a multiple of 0x200. */

/**
  * @}
  */
#define PLL_SOURCE_HSI         0
#define PLL_SOURCE_HSE         1
#define PLL_SOURCE_HSE_DIV_2   2

#define SYS_CLOCK_HSI          0
#define SYS_CLOCK_HSE          1
#define SYS_CLOCK_PLL          2
/*******************************************************************************
 *  Clock Definitions
 *******************************************************************************/
#ifdef SYSCLK_FREQ_HSE
uint32_t SystemCoreClock         = SYSCLK_FREQ_HSE;   /*!< System Clock Frequency (Core Clock) */

#elif defined SYSCLK_FREQ_24MHz
uint32_t SystemCoreClock         = SYSCLK_FREQ_24MHz; /*!< System Clock Frequency (Core Clock) */

#elif defined SYSCLK_FREQ_36MHz
uint32_t SystemCoreClock         = SYSCLK_FREQ_36MHz; /*!< System Clock Frequency (Core Clock) */

#elif defined SYSCLK_FREQ_48MHz
uint32_t SystemCoreClock         = SYSCLK_FREQ_48MHz; /*!< System Clock Frequency (Core Clock) */

#elif defined SYSCLK_FREQ_XXMHz
  #define SYSTEM_CLOCK        SYSCLK_FREQ_XXMHz;      /*!< System Clock Frequency (Core Clock) */
  #define PLL_SOURCE          PLL_SOURCE_HSE
  #define SYS_CLOCK_SRC       SYS_CLOCK_PLL
uint32_t    SystemCoreClock = SYSCLK_FREQ_XXMHz;

#elif defined SYSCLK_HSI_24MHz
uint32_t SystemCoreClock         = SYSCLK_HSI_24MHz; /*!< System Clock Frequency (Core Clock) */

#elif defined SYSCLK_HSI_36MHz
uint32_t SystemCoreClock         = SYSCLK_HSI_36MHz; /*!< System Clock Frequency (Core Clock) */

#elif defined SYSCLK_HSI_48MHz
uint32_t SystemCoreClock         = SYSCLK_HSI_48MHz; /*!< System Clock Frequency (Core Clock) */

#elif defined SYSCLK_HSI_XXMHz
  #define SYSTEM_CLOCK         SYSCLK_HSI_XXMHz;     /*!< System Clock Frequency (Core Clock) */
  #define PLL_SOURCE           PLL_SOURCE_HSI
  #define SYS_CLOCK_SRC        SYS_CLOCK_PLL
uint32_t    SystemCoreClock = SYSCLK_HSI_XXMHz;

#else /*!< HSI Selected as System Clock source */
uint32_t SystemCoreClock         = HSI_VALUE; /*!< System Clock Frequency (Core Clock) */

#endif

__I uint8_t AHBPrescTable[16] =
{
    0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9
};

/**
  * @}
  */

static void SetSysClock(void);

#ifdef SYSCLK_FREQ_HSE
static void SetSysClockToHSE(void);
#elif defined SYSCLK_FREQ_24MHz
static void SetSysClockTo24(void);
#elif defined SYSCLK_FREQ_36MHz
static void SetSysClockTo36(void);
#elif defined SYSCLK_FREQ_48MHz
static void SetSysClockTo48(void);

#elif defined SYSCLK_HSI_24MHz
static void SetSysClockTo24_HSI(void);
#elif defined SYSCLK_HSI_36MHz
static void SetSysClockTo36_HSI(void);
#elif defined SYSCLK_HSI_48MHz
static void SetSysClockTo48_HSI(void);
#elif (defined SYSCLK_FREQ_XXMHz) || (defined SYSCLK_HSI_XXMHz)
void SetSysClockToDefine(void);
#endif

#ifdef DATA_IN_ExtSRAM
static void SystemInit_ExtMemCtl(void);
#endif /* DATA_IN_ExtSRAM */
__WEAK void SysTick_Handler_CALL(void)
{
}

/**
  * @}
  */

/**
  * @brief  use to return the pllm&plln.
  * @param  pllclkSourceFrq : PLL source clock frquency;
          pllclkFrq : Target PLL clock frquency;
          plln : PLL factor PLLN
          pllm : PLL factor PLLM
  * @retval amount of error
  */
uint32_t AutoCalPllFactor(uint32_t pllclkSourceFrq, uint32_t pllclkFrq, uint8_t *plln, uint8_t *pllm)
{
    uint32_t n, m;
    uint32_t tempFrq;
    uint32_t minDiff = pllclkFrq;
    uint8_t  flag    = 0;

    for (m = 0; m < 4; m++)
    {
        for (n = 0; n < 64; n++)
        {
            tempFrq = pllclkSourceFrq * (n + 1) / (m + 1);
            tempFrq = (tempFrq > pllclkFrq) ? (tempFrq - pllclkFrq) : (pllclkFrq - tempFrq);

            if (minDiff > tempFrq)
            {
                minDiff = tempFrq;
                *plln   = n;
                *pllm   = m;
            }

            if (minDiff == 0)
            {
                flag = 1;
                break;
            }
        }

        if (flag != 0)
        {
            break;
        }
    }

    return (minDiff);
}

/**
  * @}
  */

/**
  * @brief  Setup the microcontroller system
  *         Initialize the Embedded Flash Interface, the PLL and update the
  *         SystemCoreClock variable.
  * @note   This function should be used only after reset.
  * @param  None
  * @retval None
  */
void SystemInit(void)
{
    /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
    /* Set HSION bit */
    RCC->CR |= (uint32_t)0x00000001;

    /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
    RCC->CFGR &= (uint32_t)0xF0FF0000;

    /* Reset HSEON, CSSON and PLLON bits */
    RCC->CR &= (uint32_t)0xFEF6FFFF;

    /* Reset HSEBYP bit */
    RCC->CR &= (uint32_t)0xFFFBFFFF;

    /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
    RCC->CFGR &= (uint32_t)0xFF00FFFF;
    RCC->CR   &= (uint32_t)0x000FFFFF;

    /* Disable all interrupts and clear pending bits  */
    RCC->CIR = 0x009F0000;

    /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
    /* Configure the Flash Latency cycles and enable prefetch buffer */
    SetSysClock();
}

/**
  * @brief  Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
  * @param  None
  * @retval None
  */
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
    SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
    SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
    SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
    SetSysClockTo48();
#elif defined SYSCLK_HSI_24MHz
    SetSysClockTo24_HSI();
#elif defined SYSCLK_HSI_36MHz
    SetSysClockTo36_HSI();
#elif defined SYSCLK_HSI_48MHz
    SetSysClockTo48_HSI();
#elif (defined SYSCLK_FREQ_XXMHz) || (defined SYSCLK_HSI_XXMHz)
    SetSysClockToDefine();
#endif

    /* If none of the define above is enabled, the HSI is used as System clock
       source (default after reset) */
}

#ifdef SYSCLK_FREQ_HSE
/**
  * @brief  Selects HSE as System clock source and configure HCLK, PCLK2
  *          and PCLK1 prescalers.
  * @note   This function should be used only after reset.
  * @param  None
  * @retval None
  */
static void SetSysClockToHSE(void)
{
    uint32_t i;
    __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

    /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
    /* Enable HSE */
    RCC->CR |= ((uint32_t)RCC_CR_HSEON);
    
    i = 5000;

    while (i--)
    {
    }

    /* Wait till HSE is ready and if Time out is reached exit */
    do
    {
        HSEStatus = RCC->CR & RCC_CR_HSERDY;
        StartUpCounter++;
    }
    while ((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

    if ((RCC->CR & RCC_CR_HSERDY) != RESET)
    {
        HSEStatus = (uint32_t)0x01;
    }
    else
    {
        HSEStatus = (uint32_t)0x00;
    }

    if (HSEStatus == (uint32_t)0x01)
    {
        /* Enable Prefetch Buffer */
        FLASH->ACR |= FLASH_ACR_PRFTBE;

        /* Flash 0 wait state ,bit0~2*/
        FLASH->ACR &= ~0x07;
        /* HCLK = SYSCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

        /* PCLK2 = HCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

        /* PCLK1 = HCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;

        /* Select HSE as system clock source */
        RCC->CFGR &= (uint32_t)((uint32_t) ~(RCC_CFGR_SW));

        RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE;

        /* Wait till HSE is used as system clock source */
        while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04)
        {
        }
    }
    else
    {
        /* If HSE fails to start-up, the application will have wrong clock
           configuration. User can add here some code to deal with this error */
    }
}

#elif defined SYSCLK_FREQ_24MHz
/**
  * @brief  Sets System clock frequency to 24MHz and configure HCLK, PCLK2
  *          and PCLK1 prescalers.
  * @note   This function should be used only after reset.
  * @param  None
  * @retval None
  */
static void SetSysClockTo24(void)
{
    unsigned int i;
    __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

    /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
    /* Enable HSE */
    RCC->CR |= ((uint32_t)RCC_CR_HSEON);

    i = 5000;

    while (i--)
    {
    }

    /* Wait till HSE is ready and if Time out is reached exit */
    do
    {
        HSEStatus = RCC->CR & RCC_CR_HSERDY;
        StartUpCounter++;
    }
    while ((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

    if ((RCC->CR & RCC_CR_HSERDY) != RESET)
    {
        HSEStatus = (uint32_t)0x01;
    }
    else
    {
        HSEStatus = (uint32_t)0x00;
    }

    if (HSEStatus == (uint32_t)0x01)
    {
        /* Enable Prefetch Buffer */
        FLASH->ACR |= FLASH_ACR_PRFTBE;

        /* Flash 0 wait state ,bit0~2*/
        FLASH->ACR &= ~0x07;

        FLASH->ACR |= 0x00;

        /* HCLK = SYSCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

        /* PCLK2 = HCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

        /* PCLK1 = HCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;

        RCC->PLL1CFGR &= (uint32_t)0x1F00F8FC;

        RCC->PLL1CFGR |= (0 << 29) | (3 << 16) | (1 << 8) | (1 << 0);

        /* Enable PLL */
        RCC->CR |= RCC_CR_PLL1ON;

        /* Wait till PLL is ready */
        while ((RCC->CR & RCC_CR_PLL1RDY) == 0)
        {
        }

        /* Select PLL as system clock source */
        RCC->CFGR &= (uint32_t)((uint32_t) ~(RCC_CFGR_SW));

        RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL1;

        /* Wait till PLL is used as system clock source */
        while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
        {
        }
    }
    else
    {
        /* If HSE fails to start-up, the application will have wrong clock
           configuration. User can add here some code to deal with this error */
    }
}

#elif defined SYSCLK_FREQ_36MHz
/**
  * @brief  Sets System clock frequency to 36MHz and configure HCLK, PCLK2
  *          and PCLK1 prescalers.
  * @note   This function should be used only after reset.
  * @param  None
  * @retval None
  */
static void SetSysClockTo36(void)
{
    unsigned int i;
    __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

    /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
    /* Enable HSE */
    RCC->CR |= ((uint32_t)RCC_CR_HSEON);

    i = 5000;

    while (i--)
    {
    }

    /* Wait till HSE is ready and if Time out is reached exit */
    do
    {
        HSEStatus = RCC->CR & RCC_CR_HSERDY;
        StartUpCounter++;
    }
    while ((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

    if ((RCC->CR & RCC_CR_HSERDY) != RESET)
    {
        HSEStatus = (uint32_t)0x01;
    }
    else
    {
        HSEStatus = (uint32_t)0x00;
    }

    if (HSEStatus == (uint32_t)0x01)
    {
        /* Enable Prefetch Buffer */
        FLASH->ACR |= FLASH_ACR_PRFTBE;

        /* Flash 0 wait state ,bit0~2*/
        FLASH->ACR &= ~0x07;

        FLASH->ACR |= 0x01;
        /* HCLK = SYSCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

        /* PCLK2 = HCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

        /* PCLK1 = HCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;

        RCC->PLL1CFGR &= (uint32_t)0x1F00F8FC;

        RCC->PLL1CFGR |= (0 << 29) | (5 << 16) | (1 << 8) | (1 << 0);

        /* Enable PLL */
        RCC->CR |= RCC_CR_PLL1ON;

        /* Wait till PLL is ready */
        while ((RCC->CR & RCC_CR_PLL1RDY) == 0)
        {
        }

        /* Select PLL as system clock source */
        RCC->CFGR &= (uint32_t)((uint32_t) ~(RCC_CFGR_SW));

        RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL1;

        /* Wait till PLL is used as system clock source */
        while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
        {
        }
    }
    else
    {
        /* If HSE fails to start-up, the application will have wrong clock
           configuration. User can add here some code to deal with this error */
    }
}

#elif defined SYSCLK_FREQ_48MHz
/**
  * @brief  Sets System clock frequency to 48MHz and configure HCLK, PCLK2
  *          and PCLK1 prescalers.
  * @note   This function should be used only after reset.
  * @param  None
  * @retval None
  */
static void SetSysClockTo48(void)
{
    int i;
    __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

    /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
    /* Enable HSE */
    RCC->CR |= ((uint32_t)RCC_CR_HSEON);
    
    i = 5000;

    while (i--)
    {
    }

    /* Wait till HSE is ready and if Time out is reached exit */
    do
    {
        HSEStatus = RCC->CR & RCC_CR_HSERDY;
        StartUpCounter++;
    }
    while ((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

    if ((RCC->CR & RCC_CR_HSERDY) != RESET)
    {
        HSEStatus = (uint32_t)0x01;
    }
    else
    {
        HSEStatus = (uint32_t)0x00;
    }

    if (HSEStatus == (uint32_t)0x01)
    {
        /* Enable Prefetch Buffer */
        FLASH->ACR |= FLASH_ACR_PRFTBE;
        /* Flash 0 wait state ,bit0~2*/
        FLASH->ACR &= ~0x07;

        FLASH->ACR |= 0x01;
        /* HCLK = SYSCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

        /* PCLK2 = HCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

        /* PCLK1 = HCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;

        RCC->PLL1CFGR &= (uint32_t)0x1F00F8FC;

        RCC->PLL1CFGR |= (0 << 29) | (5 << 16) | (1 << 8) | (1 << 0);

        /* Enable PLL */
        RCC->CR |= RCC_CR_PLL1ON;

        /* Wait till PLL is ready */
        while ((RCC->CR & RCC_CR_PLL1RDY) == 0)
        {
        }

        /* Select PLL as system clock source */
        RCC->CFGR &= (uint32_t)((uint32_t) ~(RCC_CFGR_SW));

        RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL1;

        /* Wait till PLL is used as system clock source */
        while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS_PLL1) != (uint32_t)0x08)
        {
        }
    }
    else
    {
        /* If HSE fails to start-up, the application will have wrong clock
           configuration. User can add here some code to deal with this error */
    }
}

#elif defined SYSCLK_HSI_24MHz
void SetSysClockTo24_HSI()
{
    unsigned char temp = 0;

    RCC->CR |= RCC_CR_HSION;

    while (!(RCC->CR & RCC_CR_HSIRDY))
    {
    }

    RCC->CFGR = RCC_CFGR_PPRE1_2;      //APB1=DIV2;APB2=DIV1;AHB=DIV1;

    RCC->CR &= ~(RCC_CR_PLL1ON);

    RCC->PLL1CFGR &= (uint32_t)0x1F00F8FC;

    RCC->PLL1CFGR |= (0 << 29) | (5 << 16) | (1 << 8);

    FLASH->ACR = FLASH_ACR_PRFTBE;

    RCC->CR |= RCC_CR_PLL1ON;

    while (!(RCC->CR & RCC_CR_PLL1RDY))
    {
    }

    RCC->CFGR &= ~RCC_CFGR_SW;

    RCC->CFGR |= RCC_CFGR_SW_PLL1;

    while (temp != 0x02)
    {
        temp  = RCC->CFGR >> 2;
        temp &= 0x03;
    }
}

#elif defined SYSCLK_HSI_36MHz
void SetSysClockTo36_HSI()
{
    unsigned char temp = 0;

    RCC->CR |= RCC_CR_HSION;

    while (!(RCC->CR & RCC_CR_HSIRDY))
    {
    }

    RCC->CFGR = RCC_CFGR_PPRE1_2;      //APB1=DIV2;APB2=DIV1;AHB=DIV1;

    RCC->CR &= ~(RCC_CR_PLL1ON);

    RCC->PLL1CFGR &= (uint32_t)0x1F00F8FC;

    RCC->PLL1CFGR |= (0 << 29) | (8 << 16) | (1 << 8);

    FLASH->ACR = FLASH_ACR_LATENCY_1 | FLASH_ACR_PRFTBE;

    RCC->CR |= RCC_CR_PLL1ON;

    while (!(RCC->CR & RCC_CR_PLL1RDY))
    {
    }

    RCC->CFGR &= ~RCC_CFGR_SW;

    RCC->CFGR |= RCC_CFGR_SW_PLL1;

    while (temp != 0x02)
    {
        temp  = RCC->CFGR >> 2;
        temp &= 0x03;
    }
}

#elif defined SYSCLK_HSI_48MHz
void SetSysClockTo48_HSI()
{
    unsigned char temp = 0;

    RCC->CR |= RCC_CR_HSION;

    while (!(RCC->CR & RCC_CR_HSIRDY))
    {
    }

    RCC->CFGR = RCC_CFGR_PPRE1_2;      //APB1=DIV2;APB2=DIV1;AHB=DIV1;

    RCC->CR &= ~(RCC_CR_PLL1ON);

    RCC->PLL1CFGR &= (uint32_t)0x1F00F8FC;

    RCC->PLL1CFGR |= (0 << 29) | (11 << 16) | (1 << 8);

    FLASH->ACR = FLASH_ACR_LATENCY_1 | FLASH_ACR_PRFTBE;

    RCC->CR |= RCC_CR_PLL1ON;

    while (!(RCC->CR & RCC_CR_PLL1RDY))
    {
    }

    RCC->CFGR &= ~RCC_CFGR_SW;

    RCC->CFGR |= RCC_CFGR_SW_PLL1;

    while (temp != 0x02)
    {
        temp  = RCC->CFGR >> 2;
        temp &= 0x03;
    }
}

#endif

#if (defined SYSCLK_FREQ_XXMHz) || (defined SYSCLK_HSI_XXMHz)
/**
  * @brief  Setup the microcontroller system
  *         Initialize the Embedded Flash Interface, the PLL and update the
  *         SystemCoreClock variable.
  * @note   This function should be used only after reset.
  * @param  pllclkSourceFrq:PLL source clock frquency;
          pllclkFrq:Target PLL clock frquency;
  * @retval None
  */
void SetSysClockToDefine(void)
{
    __IO uint32_t StartUpCounter = 0, ClkSrcStatus = 1;
    uint32_t temp;
    uint8_t plln, pllm, pllp;
    uint32_t i;

  #if ((SYS_CLOCK_SRC == SYS_CLOCK_PLL) && (PLL_SOURCE == PLL_SOURCE_HSE)) || (SYS_CLOCK_SRC == SYS_CLOCK_HSE)
    RCC->CR |= ((uint32_t)RCC_CR_HSEON); //config HSE clock
    
    i = 5000;

    while (i--)
    {
    }

    do
    {
        ClkSrcStatus = RCC->CR & RCC_CR_HSERDY;
        StartUpCounter++;
    }
    while ((ClkSrcStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

    if ((RCC->CR & RCC_CR_HSERDY) != RESET)
    {
        ClkSrcStatus = (uint32_t)0x01;
        i = 5000;

        while (i--)
        {
        }
    }
    else
    {
        ClkSrcStatus = (uint32_t)0x00;
    }
  #endif
    SystemCoreClock = SYSTEM_CLOCK;

    if (ClkSrcStatus == (uint32_t)0x01)
    {
        /* Config FLASH latency */
        FLASH->ACR |= FLASH_ACR_PRFTBE;
        FLASH->ACR &= ~0x07;
        temp = (SystemCoreClock - 1) / 24000000;

        if (temp > 7)
        {
            temp = 7;
        }

        FLASH->ACR |= temp;

        RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

        /* PCLK2 = HCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

        /* PCLK1 = HCLK */
        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;

        /* Config pll clock */
  #if (SYS_CLOCK_SRC == SYS_CLOCK_PLL)
        RCC->PLL1CFGR &= (uint32_t)0xFFFFFFFC;
    #if (PLL_SOURCE == PLL_SOURCE_HSI)
        temp = HSI_VALUE_PLL_ON;
        RCC->PLL1CFGR &= ~(uint32_t)0x00000001;
    #elif (PLL_SOURCE == PLL_SOURCE_HSE)
        temp = HSE_VALUE;
        //RCC->CFGR |= (uint32_t)RCC_CFGR_SWS_PLL1;
        RCC->PLL1CFGR |= (uint32_t)RCC_PLL1CFGR_PLL1SRC;
    #elif (PLL_SOURCE == PLL_SOURCE_HSE_DIV_2)
        temp = HSE_VALUE / 2;
        RCC->PLLCFGR |= (uint32_t)RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE;
    #endif

        pllp = 1;
        AutoCalPllFactor(temp / 2, SystemCoreClock, &plln, &pllm);

        //RCC->PLL1CFGR &= (uint32_t)0x1F00F8C3;
        RCC->PLL1CFGR &= ~((7 << 29) | (255 << 16) | (7 << 8));
        RCC->PLL1CFGR |= (pllm << 29) | (plln << 16) | (pllp << 8) | (0x2 << 4) | (0x3 << 2);

        RCC->CR |= RCC_CR_PLL1ON;

        while ((RCC->CR & RCC_CR_PLL1RDY) == 0)
        {
        }
  #endif

        /* select system clock */
        RCC->CFGR &= (uint32_t)((uint32_t) ~(RCC_CFGR_SW));

        RCC->CFGR |= (uint32_t)SYS_CLOCK_SRC;

        while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)(SYS_CLOCK_SRC << 2))
        {
        }
    }
    else
    {
    }
}

#endif
/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */
/*-------------------------(C) COPYRIGHT 2021 MindMotion ----------------------*/

